--------------------------------------------------------------------------------
-- Company: Residencia
-- Engineer:
--
-- Create Date:   15:59:47 12/28/2009
-- Design Name:   
-- Module Name:   C:/Custom32Processor/MySOC/test_ALU.vhd
-- Project Name:  MySOC
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: ALU
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

-- General package
use work.GeneralProperties.ALL;
 
ENTITY test_ALU IS
END test_ALU;
 
ARCHITECTURE behavior OF test_ALU IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT ALU
    PORT(
           A            : in  STD_LOGIC_VECTOR ((bus_size - 1) downto 0);
           B            : in  STD_LOGIC_VECTOR ((bus_size - 1) downto 0);
			  CarryIn      : in std_logic;
           AluSel       : in  ALU_operations;
			  ShifterSel   : in Shifter_operations;
           Output       : out  STD_LOGIC_VECTOR ((bus_size - 1) downto 0);
			  FlagCarry    : out std_logic;
			  FlagZero     : out std_logic;
			  FlagSign     : out std_logic;
			  FlagOverflow : out std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal A : std_logic_vector((bus_size-1) downto 0) := (others => '0');
   signal B : std_logic_vector((bus_size-1) downto 0) := (others => '0');
	signal CarryIn : std_logic := '0';
   signal AluSel : ALU_operations := op_pass;
   signal ShifterSel : Shifter_operations := op_pass;

 	--Outputs
   signal Output       : std_logic_vector((bus_size-1) downto 0);
	signal FlagCarry    : std_logic;
	signal FlagZero     : std_logic;
	signal FlagSign     : std_logic;
	signal FlagOverflow : std_logic;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: ALU PORT MAP (
          A => A,
          B => B,
			 CarryIn => CarryIn,
          AluSel => AluSel,
          ShifterSel => ShifterSel,
          Output => Output,
			 FlagCarry => FlagCarry,
			 FlagZero => FlagZero,
			 FlagSign => FlagSign,
			 FlagOverflow => FlagOverflow
        );
 
 
   -- Stimulus process
   stim_proc: process
   begin		      
      wait for 200 ns;

      REPORT "Writing  A=2 B=3... (op_pass)" SEVERITY WARNING;
		A <= conv_std_logic_vector(2, bus_size);
		B <= conv_std_logic_vector(3, bus_size);		
		AluSel <= op_pass;
		ShifterSel <= op_pass;
		wait for 200 ns;
		
		REPORT "Writing  A+B=5 ..." SEVERITY WARNING;
		AluSel <= op_add;		
		wait for 200 ns;
		
		REPORT "Writing  A-B=-1 (Should also have sign Flag)..." SEVERITY WARNING;
		AluSel <= op_sub;		
		wait for 200 ns;

      REPORT "Writing  A+B+Carry=5 ..." SEVERITY WARNING;
		CarryIn <= '1';
		AluSel <= op_add;		
		wait for 200 ns;

      REPORT "Writing  A-B-Carry=-1 (Should also have sign Flag)..." SEVERITY WARNING;
		CarryIn <= '1';
		AluSel <= op_sub;		
		wait for 200 ns;		
		
		REPORT "Writing  A++=3 ..." SEVERITY WARNING;
		CarryIn <= '0';
		AluSel <= op_inc;		
		wait for 200 ns;	
		
		REPORT "Writing  A--=1 ..." SEVERITY WARNING;
		AluSel <= op_dec;		
		wait for 200 ns;
		
		REPORT "Writing  A=4 B=4... (op_pass)" SEVERITY WARNING;
		A <= conv_std_logic_vector(4, bus_size);
		B <= conv_std_logic_vector(4, bus_size);
		AluSel <= op_pass;
		ShifterSel <= op_pass;		
		wait for 200 ns;
		
		REPORT "Writing  A-B=0 (zero flag) ..." SEVERITY WARNING;
		AluSel <= op_sub;		
		wait for 200 ns;
		
		REPORT "Writing  A and B=4 ..." SEVERITY WARNING;
		AluSel <= op_and;
		wait for 200 ns;
		
		REPORT "Writing  A or B=4 ..." SEVERITY WARNING;
		AluSel <= op_or;		
		wait for 200 ns;
		
		REPORT "Writing  not A = -5" SEVERITY WARNING;
		AluSel <= op_not;
		wait for 200 ns;
		
		-- Test for shifter
		REPORT "Writing  A=1 B=1... (op_pass)" SEVERITY WARNING;
		A <= conv_std_logic_vector(1, bus_size);
		B <= conv_std_logic_vector(1, bus_size);
		AluSel <= op_pass;
		ShifterSel <= op_pass;
		wait for 200 ns;	
		
		REPORT "Shift right A[2]=1" SEVERITY WARNING;
		A <= conv_std_logic_vector(2, bus_size);
		ShifterSel <= op_shift_right;
		wait for 200 ns;

      -- Shift Left
		REPORT "Shift left A[1]=2" SEVERITY WARNING;
		ShifterSel <= op_shift_left;				
		A <= conv_std_logic_vector(1, bus_size);
		wait for 200 ns;						
		
		-- Rotate right 
		REPORT "Rotate right A=0b0011" SEVERITY WARNING;
		A <= conv_std_logic_vector(3, bus_size);
		ShifterSel <= op_rotate_right;
		wait for 200 ns;
		
		REPORT "Test Overflow addition A=2^(15)-1 B=2^(15)-3 should get overflow and sign flags" SEVERITY WARNING;
		A <= conv_std_logic_vector(2**(bus_size-1)-1, bus_size);
		B <= conv_std_logic_vector(2**(bus_size-1)-3, bus_size);
		ShifterSel <= op_pass;
		AluSel <= op_add;		
		wait for 200 ns;				
		
		REPORT "Test Overflow subtraction A=2^(15)-1 B=2^(15)-3 should get overflow and sign flags" SEVERITY WARNING;
		A <= conv_std_logic_vector(2**(bus_size-1), bus_size);
		B <= conv_std_logic_vector(2**(bus_size-1), bus_size);
		ShifterSel <= op_pass;
		AluSel <= op_add;		
		wait for 200 ns;				
		      
		wait;
   end process;

END;
